package com.doublefish.doublefishrobot.ui.home.s6;

import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.content.res.AppCompatResources;

import com.doublefish.doublefishrobot.R;
import com.doublefish.doublefishrobot.base.BaseActivity;
import com.doublefish.doublefishrobot.ui.home.widget.ProgressView;
import com.doublefish.doublefishrobot.utils.DebounceOnClickListener;
import com.doublefish.doublefishrobot.utils.MessageEvent;
import com.doublefish.doublefishrobot.utils.ble.DFBleManager;
import com.doublefish.doublefishrobot.utils.ble.DFS6ProtocolManager;
import com.doublefish.doublefishrobot.utils.ble.bean.BleScriptStatusBean;
import com.doublefish.doublefishrobot.utils.ble.bean.OnBleResponseHandler;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 作者:dugaofeng on 2024/10/24 10:21
 */
public class S6ModeBallActivity extends BaseActivity {

    @BindView(R.id.tv_title)
    TextView titleTV;

    @BindView(R.id.point_ble_state)
    View bleStatePoint;
    @BindView(R.id.tv_ble_state)
    TextView bleStateTV;
    @BindView(R.id.point_device_state)
    View deviceStatePoint;
    @BindView(R.id.tv_device_state)
    TextView deviceStateTV;

    @BindView(R.id.rl_content)
    ProgressView progressView;
    @BindView(R.id.tv_hint_time)
    TextView hintTimeTV;
    @BindView(R.id.tv_time)
    TextView timeTV;
    @BindView(R.id.tv_hint_count)
    TextView hintCountTV;
    @BindView(R.id.tv_count)
    TextView countTV;

    @BindView(R.id.tv_pause)
    TextView pauseTV;
    @BindView(R.id.tv_stop)
    TextView stopTV;

    private String modeName;
    //mark - 发球脚本相关
    private boolean isSystem;     //是否是系统定义的48种模式
    private int dirCode;          //目录
    private String fileName;      //脚本名
    private String script;        //脚本内容
    private int loopInterval;  //循环间隔 ms 默认1000
    private boolean isTime;    //时长还是次数   YES时长   NO次数
    private int time;          //时长 (单位s 不是ms)
    private int count;         //次数

    //mark -
    private int bleState;  //状态 0.默认（未知） 1.连接  2.断开
    private int state;     //状态 0.默认（未知） 1.空闲  2.发球中  3.等待补球  4.卡球 5.暂停发球

    //定时器
    private Timer timer = null;
    private int errorFlag; //错误标记
    private int emptyFlag; //空球标记
    private int lockFlag;  //卡球标记

    //自定义脚本的intent
    public static Intent createScriptIntent(Context context,
                                      String name,
                                      boolean isSystem,
                                      String script,
                                      int loopInterval,
                                      boolean isTime,
                                      int time,
                                      int count) {
        Intent intent = new Intent(context, S6ModeBallActivity.class);
        intent.putExtra("modeName", name);
        intent.putExtra("isSystem", isSystem);
        intent.putExtra("script", script);
        intent.putExtra("loopInterval", loopInterval);
        intent.putExtra("isTime", isTime);
        intent.putExtra("time", time);
        intent.putExtra("count", count);
        return intent;
    }

    //内置模式的intent
    public static Intent createInnerIntent(Context context,
                                           String name,
                                           boolean isSystem,
                                           int dir,
                                           String fileName,
                                           int loopInterval,
                                           boolean isTime,
                                           int time,
                                           int count) {
        Intent intent = new Intent(context, S6ModeBallActivity.class);
        intent.putExtra("modeName", name);
        intent.putExtra("isSystem", true);
        intent.putExtra("dirCode", dir);
        intent.putExtra("fileName", fileName);
        intent.putExtra("loopInterval", loopInterval);
        intent.putExtra("isTime", isTime);
        intent.putExtra("time", time);
        intent.putExtra("count", count);
        return intent;
    }

    @Override
    protected void onDestroy() {
        DFS6ProtocolManager.getInstance().stopScript();
        stopTimer();
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_mode_ball_s6;
    }

    @Override
    protected void initView() {

    }

    @Override
    protected void initListener() {
        pauseTV.setOnClickListener(new DebounceOnClickListener() {
            @Override
            protected void onClickView(View view) {
                if (pauseTV.isSelected()) {
                    //恢复发球
                    resumeScript();
                } else {
                    //暂停发球
                    pauseScript();
                }
            }
        });
        stopTV.setOnClickListener(new DebounceOnClickListener() {
            @Override
            protected void onClickView(View view) {
                if (stopTV.isSelected()) {
                    //再次训练
                    serverBall();
                } else {
                    //停止发球
                    stopScript();
                }
            }
        });

        EventBus.getDefault().register(this);
    }

    @Override
    protected void initData() {
        Intent intent = getIntent();

        String modeName = intent.getStringExtra("modeName");
        if (modeName == null || modeName.length() == 0) {
            modeName = getString(R.string.custom);
        }
        titleTV.setText(modeName);

        isSystem = intent.getBooleanExtra("isSystem", false);
        dirCode = intent.getIntExtra("dirCode", 0);
        fileName = intent.getStringExtra("fileName");
        script = intent.getStringExtra("script");

        loopInterval = intent.getIntExtra("loopInterval", 0);
        isTime = intent.getBooleanExtra("isTime", false);
        time = intent.getIntExtra("time", 0);   //时长 (单位s 不是ms)
        count = intent.getIntExtra("count", 0);

        //发球
        serverBall();

        setBleState(DFBleManager.getInstance().isDidConnectBlueTooth() ? 1 : 2);

        if (isTime) {
            hintTimeTV.setText(R.string.rest_time);
            timeTV.setText("00:00");
            hintCountTV.setText(R.string.ball_count);
        } else {
            hintTimeTV.setText(R.string.ball_time);
            hintCountTV.setText(R.string.rest_ball);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        if (MessageEvent.BLE_CONNECT_STATE_SUCCESS.equals(event.getTag())) {
            setBleState(1);
        } else if (MessageEvent.BLE_CONNECT_STATE_OTHER.equals(event.getTag())) {
            setBleState(2);
        }
    }

    //region 发球
    //发球
    private void serverBall() {
        OnBleResponseHandler handler = new OnBleResponseHandler() {
            @Override
            public boolean onResponse(boolean success, int status, Object res) {
                if (success) {
                    setState(2);
                    startTimer();
                } else {
                    if (res instanceof String) {
                        showToast((String) res);
                    }
                }
                return false;
            }
        };

        if (DFBleManager.getInstance().curDeviceIsProtocolTypeS6()) {
            if (isSystem) {
                DFS6ProtocolManager.getInstance().runScript(dirCode, fileName, loopInterval, isTime, time, count, handler);
            } else {
                DFS6ProtocolManager.getInstance().writeAndRunTempScript(script, loopInterval, isTime, time, count, handler);
            }
        }
    }

    private void stopScript() {
        if (DFBleManager.getInstance().curDeviceIsProtocolTypeS6()) {
            DFS6ProtocolManager.getInstance().stopScript(new OnBleResponseHandler() {
                @Override
                public boolean onResponse(boolean success, int status, Object res) {
                    if (success) {
                        stopTimer();
                        setState(1);
                    } else {
                        if (res instanceof String) {
                            showToast((String) res);
                        }
                    }
                    return false;
                }
            });
        }
    }

    private void resumeScript() {
        if (DFBleManager.getInstance().curDeviceIsProtocolTypeS6()) {
            DFS6ProtocolManager.getInstance().resumeScript(new OnBleResponseHandler() {
                @Override
                public boolean onResponse(boolean success, int status, Object res) {
                    if (success) {
                        setState(2);
                        startTimer();
                    } else {
                        if (res instanceof String) {
                            showToast((String) res);
                        }
                    }
                    return false;
                }
            });
        }
    }

    private void pauseScript() {
        if (DFBleManager.getInstance().curDeviceIsProtocolTypeS6()) {
            DFS6ProtocolManager.getInstance().pauseScript(new OnBleResponseHandler() {
                @Override
                public boolean onResponse(boolean success, int status, Object res) {
                    if (success) {
                        setState(5);
                        stopTimer();
                    } else {
                        if (res instanceof String) {
                            showToast((String) res);
                        }
                    }
                    return false;
                }
            });
        }
    }
    //endregion

    //region 定时器
    private void startTimer() {
        if (timer != null) {
            return;
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                timerAction();
            }
        }, 1000, 1000);
    }
    private void stopTimer() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    private void timerAction() {
        if (DFBleManager.getInstance().curDeviceIsProtocolTypeS6()) {
            //读取发球机状态
            DFS6ProtocolManager.getInstance().getScriptState(new OnBleResponseHandler() {
                @Override
                public boolean onResponse(boolean success, int status, Object res) {
                    if (!success
                            || (status != 0)
                            || !(res instanceof BleScriptStatusBean)) {
                        //蓝牙数据出现错误
                        //连错3次 就可以认为真的错了
                        errorFlag++;
                        if (errorFlag >= 3) {
                            stopTimer();
                            showToast(getString(R.string.fail_get_robot_state));
                            setState(0);
                            errorFlag = 0;
                        }
                        return false;
                    }

                    BleScriptStatusBean bean = (BleScriptStatusBean) res;
                    int deviceStatus = bean.getStatus();
                    if (deviceStatus == 0x0) {
                        //正常工作
                        errorFlag = 0;
                        emptyFlag = 0;
                        refresh(bean);
                    } else if (deviceStatus == 0x0a) {
                        //发球机没有球  连续3次 就可以认为真的没有求球
                        emptyFlag++;
                        if (emptyFlag >= 3) {
                            stopTimer();
                            showToast(getString(R.string.no_ball_in_robot));
                            setState(3);
                            emptyFlag = 0;
                        }
                    } else if (deviceStatus == 0x0b) {
                        //发球机卡球 连续3次 就可以认为真的卡球
                        lockFlag++;
                        if (lockFlag >= 3) {
                            stopTimer();
                            showToast(getString(R.string.lock_ball_in_robot));
                            setState(4);
                            lockFlag = 0;
                        }
                    } else {
                        errorFlag++;
                        if (errorFlag >= 3) {
                            stopTimer();
                            showToast(getString(R.string.fail_get_robot_state));
                            setState(0);
                            errorFlag = 0;
                        }
                    }
                    return false;
                }
            });
        }
    }

    //刷新界面
    private void refresh(BleScriptStatusBean bean) {
        if (bean == null) {
            return;
        }
        if (0 == state || 1 == state) {
            return;
        }

        try {
            if (isTime) {
                int currentTime = bean.getTotalTime();
                if (currentTime > time) {
                    currentTime = time;
                    setState(1);
                    stopTimer();
                } else {
//                if (state != 2 && state != 5) {
//                    setState(2);
//                }
                    progressView.setProgress(currentTime * 100 / time);
                }
                int restTime = time - currentTime;
                int h = restTime / 3600;
                int m = (restTime - (3600 * h)) / 60;
                int s = restTime % 60;
                String timeText;
                if (h > 0) {
                    timeText = String.format(Locale.getDefault(), "%02d:%02d:%02d", h, m, s);
                } else {
                    timeText = String.format(Locale.getDefault(), "%02d:%02d", m, s);
                }
                timeTV.setText(timeText);
                countTV.setText(String.valueOf(bean.getServedCount()));
            } else {
                int currentTime = bean.getTotalTime();
                int m = currentTime / 60;
                int s = currentTime % 60;
                String timeText = String.format(Locale.getDefault(), "%02d:%02d", m, s);
                timeTV.setText(timeText);
                countTV.setText(String.valueOf(bean.getPlanCount() - bean.getServedCount()));
                progressView.setProgress(bean.getServedCount() * 100 / bean.getPlanCount());

                if (bean.getPlanCount() > bean.getServedCount()) {
//                if (state != 2 && state != 5) {
//                    setState(2);
//                }
                } else {
                    if (state != 1) {
                        setState(1);
                        stopTimer();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //endregion

    public void setBleState(int bleState) {
        this.bleState = bleState;
        if (bleState == 0) {
            bleStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_grey_6));
            bleStateTV.setText(R.string.unknown);
            setState(0);
            stopTimer();
        } else if (bleState == 1) {
            bleStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_green_6));
            bleStateTV.setText(R.string.connected);
            startTimer();
        } else if (bleState == 2) {
            bleStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_red_6));
            bleStateTV.setText(R.string.disconnected);
            setState(0);
            stopTimer();
        }
    }

    //状态 0.默认（未知） 1.空闲  2.发球中  3.等待补球 4卡球 5.暂停发球
    public void setState(int state) {
        this.state = state;

        if (state == 0) {
            deviceStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_grey_6));
            deviceStateTV.setText(R.string.unknown);
            countTV.setText("0");
            timeTV.setText("00:00");

            pauseTV.setEnabled(false);
            pauseTV.setText(R.string.pause_ball);

            stopTV.setEnabled(false);
            stopTV.setText(R.string.stop_ball);
        } else if (state == 1) {
            deviceStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_green_6));
            deviceStateTV.setText(R.string.trainning_end);

            pauseTV.setEnabled(false);
            pauseTV.setText(R.string.pause_ball);

            stopTV.setEnabled(true);
            stopTV.setSelected(true);
            stopTV.setText(R.string.repeate_ball);
        } else if (state == 2) {
            deviceStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_orange_6));
            deviceStateTV.setText(R.string.trainning___);

            pauseTV.setEnabled(true);
            pauseTV.setSelected(false);
            pauseTV.setText(R.string.pause_ball);

            stopTV.setEnabled(true);
            stopTV.setSelected(false);
            stopTV.setText(R.string.stop_ball);
        } else if (state == 3) {
            deviceStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_red_6));
            deviceStateTV.setText(R.string.waiting_ball);

            pauseTV.setEnabled(true);
            pauseTV.setSelected(true);
            pauseTV.setText(R.string.resume_ball);

            stopTV.setEnabled(true);
            stopTV.setSelected(false);
            stopTV.setText(R.string.stop_ball);
        } else if (state == 4) {
            deviceStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_grey_6));
            deviceStateTV.setText(R.string.lock_ball);
            countTV.setText("0");
            timeTV.setText("00:00");

            pauseTV.setEnabled(false);
            pauseTV.setSelected(false);
            pauseTV.setText(R.string.pause_ball);

            stopTV.setEnabled(false);
            pauseTV.setSelected(false);
            stopTV.setText(R.string.stop_ball);
        }
        else if (state == 5) {
            deviceStatePoint.setBackground(AppCompatResources.getDrawable(this,R.drawable.bg_round_orange_6));
            deviceStateTV.setText(R.string.pause_ball);

            pauseTV.setEnabled(true);
            pauseTV.setSelected(true);
            pauseTV.setText(R.string.resume_ball);

            stopTV.setEnabled(true);
            stopTV.setSelected(false);
            stopTV.setText(R.string.stop_ball);
        }
    }

    @OnClick(R.id.ll_back)
    public void onBackClick() {
        finish();
    }
}
